var app = angular.module('BaseControl');

app.directive("refer", ['$compile','PublicConst', 'PublicEnum', 'PublicModule', 'PublicFunction',
    function($compile, PublicConst, PublicEnum, PublicModule, PublicFunction) {
    return {
        restrict: "E",	// 指令是一个元素 (并非属性)，备选项有"A"、"E" 和 "C"， "M" ,分别代表attribute、element、class和comment（默认值为"A"）
        scope: {
            key: '=?',
            value: '=?',
            text: '=?',
            change: '&',
            blur: '&',
            keydown: '&',
            beforeshow: '&'
        },
        templateUrl: 		// 替换HTML (使用scope中的变量)
            'modules/Base/client/views/templates/Refer.html',
        replace: true,			// 使用模板替换原始标记
        transclude: true,		// 不复制原始HTML内容
        controller: ['$scope', function($scope) {
            $scope.Module;
            $scope.DisplayText = '';
            $scope.Columns = new Array();
            $scope.ID = '-2';

            $scope.divClick = function(){
                event.stopPropagation();
            };

            $scope.textFocus = function(){
                $scope.DisplayText = $scope.value;
                $scope._InputElement.select();

                if(!$scope.IsFocuse){
                    $scope.IsFocuse = true;
                    document.addEventListener('click', $scope.BodyClick, true);
                }
            };
            $scope.textBlur = function(){
                $scope.DisplayText = $scope.text;
            };
            $scope.textKeyDown = function(){
                $scope.keydown();
            };
            $scope.IsChanging = false;
            $scope.textChange = function(afterChange){
                if($scope.DisplayText != $scope.value){
                    if($scope.DisplayText.trim() != ''){
                        $scope.IsChanging = true;
                        var condition = {};
                        condition[$scope.ValueField] = '/^' + $scope.DisplayText.trim() + '/';
                        $scope.Module.find(condition, null, 
                            function(records){
                                if(records.length > 0){
                                    $scope.key = records[0][$scope.KeyField];
                                    $scope.value = records[0][$scope.ValueField];
                                    $scope.text = records[0][$scope.TextField];

                                    if(document.activeElement == $scope._InputElement)
                                    {
                                        $scope.DisplayText = $scope.value;
                                    }
                                    else{
                                        $scope.DisplayText = $scope.text;
                                    }

                                    if(records.length > 1){
                                        if(!isCreateDataGrid){
                                            createDataGrid();
                                        }
                                        
                                        $scope.Module.Records = [];
                                        var oldCondition = $scope.Module.QueryParameter.Condition;
                                        $scope.Module.QueryParameter.Condition = condition;
                                        $scope.Module.load(condition, null, function(){
                                            $scope.Module.QueryParameter.Condition = oldCondition;
                                            $('#' + $scope.ID).modal('show');
                                        });
                                    }
                                    else{
                                        $scope.change({records: records});
                                    }
                                }                                
                                else{
                                    $scope.key = null;
                                    $scope.value = '';
                                    $scope.text = '';
                                    $scope.DisplayText = '';

                                    //$scope.$digest();
                                    $scope.change({records: []});
                                }

                                $scope.IsChanging = false;
                                if(afterChange != undefined && afterChange != null){
                                    afterChange();
                                }
                            }
                        );
                    }
                    else{
                        $scope.key = null;
                        $scope.value = '';
                        $scope.text = '';
                        $scope.DisplayText = '';

                        $scope.$digest();
                        $scope.change({records: []});

                        if(afterChange != undefined && afterChange != null){
                            afterChange();
                        }
                    }
                }
                else{
                    $scope.DisplayText = $scope.text;
                    if(afterChange != undefined && afterChange != null){
                        afterChange();
                    }
                }
            }

            var isCreateDataGrid = false;
            var createDataGrid = function(afterCreate){
                if (!isCreateDataGrid) {
                    $scope.ID = (new Date()).getTime().toString();
                    
                    var dataGridHtml = '<DataGrid module="Module" rowdblclick="rowDblClick()" isSelect="' + $scope.IsSelect.toString() + '" isedit="false" height="430px">';
                    for (var i = 0; i < $scope.Columns.length; i++) {
                        if($scope.Columns[i].Type == PublicEnum.ControlType.TextBox){
                            dataGridHtml += '<TextBoxColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></TextBoxColumn>';
                        }
                        else if($scope.Columns[i].Type == PublicEnum.ControlType.CheckBox){
                            dataGridHtml += '<CheckBoxColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></CheckBoxColumn>';
                        }
                        else if($scope.Columns[i].Type == PublicEnum.ControlType.NumberBox){
                            if($scope.Columns[i].Round != null){
                                dataGridHtml += '<NumberBoxColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" round="' + JSON.stringify($scope.Columns[i].Round) + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></NumberBoxColumn>';
                            }
                            else{
                                dataGridHtml += '<NumberBoxColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></NumberBoxColumn>';
                            }
                        }
                        else if($scope.Columns[i].Type == PublicEnum.ControlType.PercentBox){
                            if($scope.Columns[i].Round != null){
                                dataGridHtml += '<PercentBoxColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" round="' + JSON.stringify($scope.Columns[i].Round) + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></PercentBoxColumn>';
                            }
                            else{
                                dataGridHtml += '<PercentBoxColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></PercentBoxColumn>';
                            }
                        }
                        else if($scope.Columns[i].Type == PublicEnum.ControlType.DropDownList){
                            var columnEnum = eval("$scope.$parent." + $scope.Columns[i].Enum);
                            if(columnEnum != undefined){
                                $scope.Columns[i].Enum = columnEnum;
                            }
                            else{
                                $scope.Columns[i].Enum = eval("$scope.$parent.$parent." + $scope.Columns[i].Enum);
                            }
                            dataGridHtml += '<DropDownListColumn displayname="' + $scope.Columns[i].DisplayName + '" enum="Columns[' + i.toString() + '].Enum" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></DropDownListColumn>';
                        }
                        else if($scope.Columns[i].Type == PublicEnum.ControlType.Calendar){
                            if($scope.Columns[i].CalendarType == PublicEnum.DateTimeFormat.DateTime){
                                dataGridHtml += '<CalendarColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" calendartype="datetime" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></CalendarColumn>';
                            }
                            else{
                                dataGridHtml += '<CalendarColumn displayname="' + $scope.Columns[i].DisplayName + '" width="' + $scope.Columns[i].Width + '" valuefield="' + $scope.Columns[i].ValueField + '" calendartype="date" IsFilter="' + $scope.Columns[i].IsFilter.toString() + '"></CalendarColumn>';
                            }
                        }
                    }
                    dataGridHtml += '</DataGrid>';

                    $compile(dataGridHtml)($scope, function (clone, $scope) {
                        $scope._DataGridElement.appendChild(clone[0]);
                        afterCreate();
                    });

                    if($scope.IsInclude){
                        $scope._ContentElement.style.display = "inline-table";
                        $scope._ContentElement.style.top = ((document.body.clientHeight - $scope._ContentElement.getBoundingClientRect().height) / 2 - $scope._ContentElement.getBoundingClientRect().top).toString() + 'px';
                    }
                    isCreateDataGrid = true;
                }
                else{
                    afterCreate();
                }
            }
            $scope.btnClick = function() {
                if(this.Enabled){
                    if(!$scope.IsFocuse){
                        $scope.IsFocuse = true;
                        document.addEventListener('click', $scope.BodyClick, true);
                    }

                    if($scope.EntityName == undefined || $scope.EntityName == null || $scope.EntityName.trim() == ''){
                        event.stopPropagation();
                        return;
                    }
                    $scope.beforeshow({refScope: $scope});
                    createDataGrid(function(){
                        $scope.Module.load();
                    });
                }
            };
            $scope.btnRefOKClick = function(){
                if($scope.IsSelect){
                    var records = $scope.Module.getSelectRecords();

                    if(records.length > 0){
                        $scope.key = records[0][$scope.KeyField];
                        $scope.value = records[0][$scope.ValueField];
                        $scope.text = records[0][$scope.TextField];
                        $scope._InputElement.focus();

                        $scope.$digest();
                        $scope.change({records: records});
                    }
                    else{
                        PublicFunction.alert('请选择记录！');
                        event.stopPropagation();
                        return;
                    }
                }
                else{
                    if($scope.Module.FocusedRecord == null){
                        PublicFunction.alert('请选择记录！');
                        event.stopPropagation();
                        return;
                    }

                    if($scope.key != $scope.Module.FocusedRecord[$scope.KeyField]){
                        $scope.key = $scope.Module.FocusedRecord[$scope.KeyField];
                        $scope.value = $scope.Module.FocusedRecord[$scope.ValueField];
                        $scope.text = $scope.Module.FocusedRecord[$scope.TextField];

                        $('#' + $scope.ID).modal('hide');
                        $scope.DisplayText = $scope.text;
                        $scope._InputElement.focus();

                        //$scope.$digest();
                        $scope.change({records: [$scope.Module.FocusedRecord]});
                    }                    
                }                
            };
            $scope.btnRefCancelClick = function(){
                $('#' + $scope.ID).modal('hide');
            };
            $scope.rowDblClick = function(){
                if($scope.key != $scope.Module.FocusedRecord[$scope.KeyField]){
                    $scope.key = $scope.Module.FocusedRecord[$scope.KeyField];
                    $scope.value = $scope.Module.FocusedRecord[$scope.ValueField];
                    $scope.text = $scope.Module.FocusedRecord[$scope.TextField];
                    $scope.DisplayText = $scope.text;

                    //$scope.$digest();   //$scope.$parent.$digest();
                    $scope.change({records: [$scope.Module.FocusedRecord]});
                }
                $('#' + $scope.ID).modal('hide');
                $scope._InputElement.focus();
            };

            $scope.$watch(
                function(){
                    return $scope.key;
                },
                function(){
                    if(document.activeElement == $scope._InputElement)
                    {
                        $scope.DisplayText = $scope.value;
                    }
                    else{
                        $scope.DisplayText = $scope.text;
                    }
                }
            );
        }],
        link: function (scope, element, attrs) {
            scope.Enabled = true;
            scope.Visible = true;
            scope.IsSelect = false;
            scope.IsInclude = false;    //是否包含在父容器里面
            scope.IsGrid = false;

            scope.EntityName;
            scope.QueryParameter = {};
            scope.WindowTitle = '参照';
            scope.KeyField = '_id';
            scope.ValueField = 'code';
            scope.TextField = 'name';

            scope._InputElement = element[0].children[0].children[0];
            scope._ContentElement = element[0].children[1];
            scope._DataGridElement = element[0].children[1].children[0].children[0].children[1]; //angular.element(element[0].children[1].children[0].children[0].children[1]);

            if (attrs["entityname"] != undefined && attrs["entityname"].trim() != "") {
                scope.EntityName = attrs["entityname"].trim();
            }
            if (attrs["queryparameter"] != undefined && attrs["queryparameter"].trim() != "") {
                scope.QueryParameter = eval("(" + attrs["queryparameter"].trim() + ")");
            }
            if (attrs["windowtitle"] != undefined && attrs["windowtitle"].trim() != "") {
                scope.WindowTitle = attrs["windowtitle"].trim();
            }
            if (attrs["keyfield"] != undefined && attrs["keyfield"].trim() != "") {
                scope.KeyField = attrs["keyfield"].trim();
            }
            if (attrs["valuefield"] != undefined && attrs["valuefield"].trim() != "") {
                scope.ValueField = attrs["valuefield"].trim();
            }
            if (attrs["textfield"] != undefined && attrs["textfield"].trim() != "") {
                scope.TextField = attrs["textfield"].trim();
            }
            if (attrs["isselect"] != undefined && attrs["isselect"].toLocaleLowerCase() == "true") {
                scope.IsSelect = true;
            }
            if (attrs["isgrid"] != undefined && attrs["isgrid"].toLocaleLowerCase() == "true") {
                scope.IsGrid = true;
                element[0].children[0].children[0].setAttribute("class", "form-control ReferTextBox BaseControl GridBaseControl");
                element[0].children[0].children[1].children[0].setAttribute("class", "btn btn-default BaseControl GridBaseControl ReferBtn");
            }
            if (attrs["isinclude"] != undefined && attrs["isinclude"].toLocaleLowerCase() == "true") {
                scope.IsInclude = true;
            }
            if (attrs["condition"] != undefined && attrs["condition"].trim() != "") {
                scope.QueryParameter.Condition = eval("(" + attrs["condition"].trim() + ")");
            }
            if (attrs["orderby"] != undefined && attrs["orderby"].trim() != "") {
                scope.QueryParameter.OrderBy = eval("(" + attrs["orderby"].trim() + ")");
            }
            if (attrs["populate"] != undefined && attrs["populate"].trim() != "") {
                if(attrs["populate"].trim().substring(0, 1) == "{"){
                    scope.QueryParameter.Populate = eval("(" + attrs["populate"].trim() + ")");
                }
                else{
                     scope.QueryParameter.Populate = eval(attrs["populate"].trim());
                }
            }
            if (attrs["valuefield"] != undefined && attrs["valuefield"].trim() != "") {
                scope.ValueField = attrs["valuefield"].trim();
            }

            scope._InputElement.addEventListener('change', function(){ scope.textChange(); }, false);
            scope._InputElement.addEventListener('keydown', function(){ scope.textKeyDown(); }, false);

            scope.BodyClick = function(){
                if(scope.IsFocuse) {
                    var eventNode = event.srcElement;

                    while(eventNode){
                        if(eventNode == document ||eventNode == undefined || eventNode.tagName == undefined ||
                            eventNode.tagName.toLowerCase() == 'html' || eventNode.tagName.toLowerCase() == 'body'){
                            scope.IsFocuse = false;
                            document.removeEventListener('click', scope.BodyClick, true);

                            scope.blur();
                            // var checkNowChange = function(){
                            //     if(!scope.IsChanging) {
                            //         clearInterval(chack);
                            //         scope.blur();
                            //     }
                            // }
                            // var chack = setInterval(checkNowChange, 1);
                            break;
                        }
                        else if(eventNode == element[0]) {
                            break;
                        }
                        eventNode = eventNode.parentNode;
                    }
                }
            };

            for(var i=0; i<scope._DataGridElement.children.length; i++){
                var column = {
                    Type: PublicEnum.ControlType.TextBox,
                    IsFilter: true,
                    DisplayName: 'XXX',
                    Width: '100px',
                    ValueField: '_id',
                    Round: null,         //数值和百分比控件可以使用
                    Enum: null,
                    CalendarType: PublicEnum.DateTimeFormat.DateTime    //日历控件可以使用
                };

                var columnDom = scope._DataGridElement.children[i];
                if (columnDom.getAttribute("type") != undefined && columnDom.getAttribute("type").trim() != "") {
                    var type = columnDom.getAttribute("type").trim().toLowerCase();

                    if(type == 'textbox' || type == '0'){
                        column.Type = PublicEnum.ControlType.TextBox;
                    }
                    else if(type == 'checkbox' || type == '1'){
                        column.Type = PublicEnum.ControlType.CheckBox;
                    }
                    else if(type == 'numberbox' || type == '2'){
                        column.Type = PublicEnum.ControlType.NumberBox;
                    }
                    else if(type == 'percentbox' || type == '3'){
                        column.Type = PublicEnum.ControlType.PercentBox;
                    }
                    else if(type == 'dropdownlist' || type == '4'){
                        column.Type = PublicEnum.ControlType.DropDownList;
                        column.Enum = columnDom.getAttribute("enum").trim();
                    }
                    else if(type == 'calendar' || type == '6'){
                        column.Type = PublicEnum.ControlType.Calendar;
                    }
                }
                if (columnDom.getAttribute("displayname") != undefined && columnDom.getAttribute("displayname").trim() != "") {
                    column.DisplayName = columnDom.getAttribute("displayname").trim();
                }
                if (columnDom.getAttribute("width") != undefined && columnDom.getAttribute("width").trim() != "") {
                    column.Width = columnDom.getAttribute("width").trim();
                }
                if (columnDom.getAttribute("valuefield") != undefined && columnDom.getAttribute("valuefield").trim() != "") {
                    column.ValueField = columnDom.getAttribute("valuefield").trim();
                }
                if (columnDom.getAttribute("isfilter") != undefined && columnDom.getAttribute("isfilter").toLocaleLowerCase() == "false") {
                    column.IsFilter = false;
                }
                if (columnDom.getAttribute("round") != undefined && columnDom.getAttribute("round").trim() != "") {
                    var round = eval("(" + columnDom.getAttribute("round").trim() + ")");

                    var precision = 2;
                    var roundType = PublicEnum.RoundType.AccondValueRound;
                    var roundValue = 5;

                    if(round.Precision != undefined){
                        precision = round.Precision;
                    }
                    if(round.RoundType != undefined){
                        roundType = round.RoundType;
                    }
                    if(round.RoundValue != undefined){
                        roundValue = round.RoundValue;
                    }

                    column.Round = new PublicClass.Round(precision, roundType, roundValue);
                }
                if (columnDom.getAttribute("calendartype") != undefined && columnDom.getAttribute("calendartype").trim() == "date") {
                    column.CalendarType = PublicEnum.DateTimeFormat.Date;
                }                
                scope.Columns.push(column);
            }

            scope.Module = PublicModule.initModule(scope, scope.EntityName);
            scope.Module.PageSize = 10;
            if(scope.QueryParameter.Condition != undefined){
                scope.Module.QueryParameter.Condition = scope.QueryParameter.Condition;
            }
            if(scope.QueryParameter.OrderBy != undefined){
                scope.Module.QueryParameter.OrderBy = scope.QueryParameter.OrderBy;
            }
            if(scope.QueryParameter.Populate != undefined){
                scope.Module.QueryParameter.Populate = scope.QueryParameter.Populate;
            }
            scope.Module.LoadMode = PublicEnum.LoadMode.CacheAndPaging;

            scope.$watch(
                function(){
                    return attrs["enabled"] || attrs["visible"];
                },
                function(){
                    if (attrs["enabled"] != undefined && attrs["enabled"].trim().toLocaleLowerCase() == "false") {
                        scope.Enabled = false;
                    }
                    else{
                        scope.Enabled = true;
                    }
                    if (attrs["visible"] != undefined && attrs["visible"].trim().toLocaleLowerCase() == "false") {
                        scope.Visible = false;
                    }
                    else{
                        scope.Visible = true;
                    }
                }
            );
        }
    }
}]);
